package com.tbit.uqbike.webmanager.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.common.utils.TraceUtil;
import com.tbit.uqbike.annos.OperateLog;
import com.tbit.uqbike.common.ResultMsg;
import com.tbit.uqbike.constant.HttpStatus;
import com.tbit.uqbike.object.business.UserInfo;
import com.tbit.uqbike.object.pojo.dto.RideOrderRefundDTO;
import com.tbit.uqbike.object.pojo.statistics.AccountDataMonthSta;
import com.tbit.uqbike.object.pojo.vo.RideLogDetailsVO;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.ReconcileService;
import com.tbit.uqbike.service.business.ReconciliationService;
import com.tbit.uqbike.service.business.RefundService;
import com.tbit.uqbike.service.business.RideLogDetailsService;
import com.tbit.uqbike.webmanager.dto.AbnormalRecordDTO;
import com.tbit.uqbike.webmanager.req.AbnormalHandleReq;
import com.tbit.uqbike.webmanager.req.AbnormalRecordReq;
import com.tbit.uqbike.webmanager.resp.reconciliation.HandleDetailResp;
import com.tbit.uqbike.webmanager.util.Assert;
import com.tbit.uqbike.webmanager.util.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.List;
import java.util.Map;

/**
 * 对账
 * @Author HZW
 * @ClassName reconciliationController
 * @Description 对账接口
 * @date 2022/4/2 16:41
 * @Version 1.0
 */
@RestController
@RequestMapping("/operatingIncome")
@Slf4j
public class ReconcileController extends BaseController {
    @Autowired
    private ReconcileService reconcileService;
    @Autowired
    private RefundService refundService;
    @Autowired
    private RideLogDetailsService rideLogDetailsService;
    @Autowired
    private ReconciliationService reconciliationService;

    /**
     * 资金流水=骑行卡订单+会员卡订单+免押卡订单+优惠券订单+用户充值金额+押金支付金额-骑行卡订单退款-会员卡订单退款-免押卡订单退款-优惠券订单退款-充值退款金额-押金退款金额
     * 运营收益=骑行卡订单+会员卡订单+免押卡订单+优惠券订单+骑行订单支付金额-骑行卡订单退款-会员卡订单退款-免押卡订单退款-优惠券订单退款-骑行订单退款金额
     * 用户余额变更（差值）=用户充值金额+手动充值余额+骑行订单退款金额-充值退款金额-手动扣款余额-骑行订单支付金额
     * 押金变更（差值）=押金支付金额-押金退款金额
     * 资金流水=运营收益+用户余额+用户押金
     * */

    /**
     * 查询品牌每个月份的对账数据
     *
     * @param accountId 帐户id
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return {@link JsonResult}
     */
    @PostMapping("/brandOrderStatistics")
    public JsonResult brandOrderStatistics(Integer accountId, String startTime, String endTime) throws ParseException {
        List<Map<String, Object>> brandDateByTime = reconcileService.getBrandDateByTime(accountId, startTime, endTime);
        return JsonResult.ok(startPage(brandDateByTime), brandDateByTime.size());
    }


    /**
     * 查询品牌下每个区域的对账数据
     *
     * @param accountId 帐户id
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return {@link JsonResult}
     */
    @PostMapping("/accountAreaStatistics")
    public JsonResult accountAreaStatistics(Integer accountId, String startTime, String endTime) throws ParseException {
        List<AccountDataMonthSta> accountDataDaySta = reconcileService.getAreaByTime(accountId, startTime, endTime);
        return JsonResult.ok(startPage(accountDataDaySta), accountDataDaySta.size());
    }


    /**
     * 查询品牌下每个区域时间内的对账数据
     *
     * @param accountId 帐户id
     * @return {@link JsonResult}
     */
    @PostMapping("/areaDateStatistics")
    public JsonResult areaDateStatistics(Integer accountId, String dataTime) {
        List<Map<String, Object>> accountDataDaySta = reconcileService.getDateByAreaTime(accountId, dataTime);
        return JsonResult.ok(startPage(accountDataDaySta), accountDataDaySta.size());
    }


    /**
     * 骑行退款 （已弃用）
     *
     * @param accountid  区域id
     * @param orderNO    订单号
     * @param phone      电话
     * @param money      退款金额
     * @param operaPsw   密钥
     * @param refundType 退款类型
     * @return {@link JsonResult}
     * @throws ParseException 解析异常
     */
    @PostMapping("/rideRefund")
    @OperateLog(module = ModuleEnum.REFUND, methods = MethodEnum.RIDE_ORDER_REFUND_OPERATION)
    public JsonResult rideRefund(Integer accountid, String orderNO, String phone, Integer money,
                                 String operaPsw, Integer refundType, Integer isSend, String isMessage, HttpServletRequest request) throws ParseException {
        /**退款金额*/
        Assert.notNull(money, "ver.money.notNull");
        /**退款类型（0-退款到余额，1-退款到用户账上（如微信、支付宝））*/
        Assert.notNull(refundType, "ver.type.notNull");
        Assert.notNull(phone, "ver.phone.notNull");
        RideLogDetailsVO rideLogDetailsVO = rideLogDetailsService.queryByOrderId(orderNO);
        if (rideLogDetailsVO == null) {
            return JsonResult.fail("订单不存在", TraceUtil.getTraceIdByLocal());
        }
        //前端传来的退款金额字段（单位：分）
        long refundMoney = money.longValue();
        //可退罚款费用
        long returnableFineMoney = (long) (rideLogDetailsVO.getReturnableFineMoney() * 100);
        //可退骑行费用
        long returnableRideMoney = (long) (rideLogDetailsVO.getReturnableRideMoney() * 100);
        if (refundMoney > (returnableFineMoney + returnableRideMoney)) {
            return JsonResult.fail("退款金额大于剩余可退金额",TraceUtil.getTraceIdByLocal());
        }
        long refundFindMoney;
        long refundRideMoney = 0L;
        //优先退罚款
        if (refundMoney <= returnableFineMoney) {
            refundFindMoney = refundMoney;
        } else {
            //可退罚款不够退
            refundFindMoney = returnableFineMoney;
            refundRideMoney = refundMoney - returnableFineMoney;
        }
        Result result = refundService.rideOrderRefund(getLogin(ServletUtils.getRequest()),
                new RideOrderRefundDTO(rideLogDetailsVO.getUserId(), refundRideMoney, operaPsw, orderNO, refundFindMoney, 0L, isSend, isMessage));
        if (result.getCode().equals(HttpStatus.SUCCESS)) {
            return JsonResult.ok();
        } else {
            return JsonResult.fail(result.getMsg(),TraceUtil.getTraceIdByLocal());
        }

        /**操作密码校验*/
        /*if (!OperaPswConstant.DEPOSIT_OPERA_UPDATE_MONEY.equals(operaPsw)) {
            throw new BaseException(SystemCodeEnum.OPERA_PAW_ERROR);
        }

        LoginInfo login = getLogin(ServletUtils.getRequest());
        return reconcileService.refund(accountid, orderNO, phone, money, refundType, isSend, isMessage, login);*/

        /*if (flag) {
            return JsonResult.ok();
        } else {
            return JsonResult.fail("退款失败，请联系管理员");
        }*/

    }

    @RequestMapping("/excelDate")
    public JsonResult excelDate(HttpServletResponse response, OutputStream out, String dataTime, Integer accountId) {
        Assert.notNull(dataTime, "ver.time.notNull");
        Assert.notNull(accountId, "时间不能为空");
        boolean flag = reconcileService.excel(response, out, dataTime, accountId);
        if (flag) {
            return JsonResult.ok();
        } else {
            return JsonResult.fail("导出失败，请联系管理员", TraceUtil.getTraceIdByLocal());
        }
    }

    /**
     * 财务对账异常记录
     *
     * @Param AbnormalRecordReq req 请求参数
     * @return {@link ResultMsg}
     */
    @GetMapping("/abnormalRecord")
    public ResultMsg<Page<AbnormalRecordDTO>> abnormalRecord(@ModelAttribute @Valid AbnormalRecordReq req){
        return ResultMsg.success(reconciliationService.list(req));
    }

    /**
     * 财务对账异常记录导出
     *
     * @Param AbnormalRecordReq req 请求参数
     * @return {@link ResultMsg}
     */
    @GetMapping("/abnormalRecordExport")
    public void abnormalRecordExport(@ModelAttribute @Valid AbnormalRecordReq req, HttpServletResponse response) throws IOException {
        reconciliationService.export(req,response);
    }


    /**
     * 处理异常记录
     *
     * @Param AbnormalHandleReq req 请求参数
     * @return {@link ResultMsg}
     */
    @PostMapping("/handle")
    public ResultMsg<Void> handle(@RequestBody @Valid AbnormalHandleReq req){

        UserInfo userInfo =fetchUserInfo();

        reconciliationService.handleAbnormal(req,userInfo);

        return ResultMsg.success();
    }

    /**
     * 异常记录详情
     *
     * @Param recordId 异常记录id
     * @return {@link ResultMsg}
     */
    @GetMapping("/handleDetail")
    public ResultMsg<HandleDetailResp> handleDetail(Long recordId){

        return ResultMsg.success(reconciliationService.detail(recordId));
    }


}


